<template>
    <button v-leit:aaa.fff="{ background: 'red' }">按钮</button>

    <h2>自定义指令应用：用户鉴权</h2>
    <button v-user="'show-add'">增加</button>
    <button v-user="'show-del'">删除</button>
    <button v-user="'show-edit'">修改</button>

    <h2>自定义拖拽指令，元素拖拽：v-move:single</h2>
    <button v-move:single>单个元素拖动</button>

    <div style="height: 30px;"></div>
    <h2>自定义拖拽指令，元素拖拽：v-move:id="'xxxx'"</h2>
    <div v-move:id="'header'" class="drop-box">
        <div class="header" id="header"></div>
        <div>点击绑定元素中的某个id的元素进行拖动, 这里指定了点击头部id为header 的进行拖动</div>
    </div>
</template>

<script setup lang='ts'>
import type { Directive, DirectiveBinding } from 'vue'

const vLeit: Directive = {
    created() {
        console.log('指令created')
    },
    beforeMount() {
        console.log('指令beforeMount')
    },
    mounted(...args) {
        console.log('指令mounted')
        console.log('入参有', args)
    },
    beforeUpdate() {
        console.log('指令beforeUpdate')
    },
    updated() {
        console.log('指令updated')
    },
    unmounted() {
        console.log('指令unmounted')
    }
}

// 模拟用户拥有权限
const permission = [
    'leilei:show-add',
    // 'leilei:show-del',
    'leilei:show-edit'
]

const userId = 'leilei'

// 一般只会使用到mounted和updated两个钩子函数，可以使用如下函数模式简写
const vUser: Directive<HTMLElement, string> = (el, binding) => {
    // 判断该用户是否有该权限
    if (!permission.includes(userId + ':' + binding.value)) {
        el.style.display = 'none'
    }
}


// 定义拖拽指令， v-move:single 标识拖动单个元素  v-move:classname="'header'"表示点击绑定元素中的某个类的元素进行拖动
const vMove: Directive = (el: HTMLElement, binding: DirectiveBinding) => {
    const move = (moveEl: HTMLElement) => {
        el.style.position = 'fixed'

        const mouseDown = (e: MouseEvent) => {
            let x = e.clientX - el.offsetLeft
            let y = e.clientY - el.offsetTop

            const mouseMove = (e: MouseEvent) => {
                el.style.left = e.clientX - x + 'px'
                el.style.top = e.clientY - y + 'px'
            }
            // 监听移动事件
            document.addEventListener('mousemove', mouseMove)
            // 监听鼠标抬起，移除移动事件
            document.addEventListener('mouseup', () => {
                document.removeEventListener('mousemove', mouseMove)
            })
        }

        moveEl.addEventListener('mousedown', mouseDown)
    }

    if (binding.arg === 'single') {
        move(el)
    } else if (binding.arg === 'id' ) {
        const moveEl:HTMLDivElement = document.getElementById(binding.value) as HTMLDivElement
        move(moveEl)
    }
}
</script>
<style scoped>
.drop-box {
    width: 200px;
    height: 200px;
    border: 1px solid black;
}

.drop-box .header {
    width: inherit;
    height: 20px;
    background-color: black;
}
</style>